

const { ccclass, property } = cc._decorator;

@ccclass
export class Game extends cc.Component {
    @property(cc.Sprite)
    indexBall: cc.Sprite = null;// 标记第一个触底ball的ball

    @property(cc.Prefab)
    boxPrefab: cc.Prefab = null;

    @property(cc.Prefab)
    ballPrefab: cc.Prefab = null;

    @property(cc.Prefab)
    lifePrefab: cc.Prefab = null;

    @property(cc.Node)
    ground: cc.Node = null;// 地面

    @property(cc.Node)
    gameNode: cc.Node = null;

    @property(cc.Sprite)
    ballLink: cc.Sprite = null;// 轨迹条

    @property(cc.Label)
    levelLabel: cc.Label = null;

    @property(cc.Label)
    allBallsLabel: cc.Label = null;

    @property(cc.Label)
    tipsLabel: cc.Label = null;

    @property(cc.AudioClip)
    rockAudio: cc.AudioClip = null;

    @property(cc.AudioClip)
    circleAudio: cc.AudioClip = null;

    // 所有ball是否均落下
    ballDown = false
    // 是否开始游戏
    isBegin = false
    // 是否在游戏中
    isActivity = false
    // 第一个ball是否触底
    isFirstBall = false
    // 第一个触底的ball X坐标
    firstBallPositionX = 0
    // 所有小球计数
    allBalls = 1
    // 所有触底小球计数
    tampBalls = 0
    addBalls = 0
    level = 1
    score = 0
    lastBallPositionX = 0
    lastBallPositionY = 30

    onLoad () {
        // 开启物理
        cc.director.getPhysicsManager().enabled = true;
        // 开启碰撞
        cc.director.getCollisionManager().enabled = true;

        this.indexBall.node.setPosition(this.firstBallPositionX, this.lastBallPositionY);
        this.ballLink.node.setPosition(this.firstBallPositionX, this.lastBallPositionY);   

        this.ballLink.enabled = false;
        this.ground.getComponent('groundSprite').game = this;
        this.initBox();
        
        this.node.on(cc.Node.EventType.TOUCH_START, function(event){
            this.touchStart(event);
        }.bind(this), this);

        this.node.on(cc.Node.EventType.TOUCH_MOVE, function(event){
            this.touchMove(event);            
        }.bind(this), this);

        this.node.on(cc.Node.EventType.TOUCH_END, function(event){
            this.touchEnd(event);
        }.bind(this), this);

        // 生成第一层小球
        for (let i = 0; i < 6; i++) {
            let isBox = Math.ceil(Math.random() * 10) % 2;
            if (isBox == 1) {
                let newBox = cc.instantiate(this.boxPrefab);
                this.node.addChild(newBox);
                newBox.setPosition(-285 + i * (100 + 13), 450);
                let colorArr = this.hslToRgb(this.level * 0.025, 0.5, 0.5);
                newBox.color = cc.color(colorArr[0], colorArr[1], colorArr[2]);
            }
        }
    }

    initBox() {   
        this.level ++;
        this.levelLabel.getComponent(cc.Label).string = "分数：" + this.score;
        // 下移box
        if (this.isBegin == true) {
            let bottomPos = this.lastBallPositionY - this.gameNode.height / 2
            let childrenNode = this.node.children;
            for (let i = 0; i < childrenNode.length; i++) {
                let node = childrenNode[i];
                if (node.name == "boxSprite" || node.name == "lifeBox") {
                    if (node.position.y <= 450) {
                        node.y -= 108;
                        if (node.y <= bottomPos) {
                            this.showGameOver();
                            return
                        }
                    }
                }
            }
            // createBox
            let isShowLifeBox = false;
            for (let i = 0; i < 6; i++) {
                let isBox = Math.ceil(Math.random() * 10) % 2;
                if (isBox == 1) {
                    let isLife = Math.ceil(Math.random() * 10) % 2;
                    if (isLife == 1 && isShowLifeBox == false) {
                        isShowLifeBox = true;
                        let lifeBox = cc.instantiate(this.lifePrefab);
                        lifeBox.setPosition(-285 + i * (100 + 13), 450);
                        this.node.addChild(lifeBox);
                    } else {
                        let newBox = cc.instantiate(this.boxPrefab);
                        let scoreLabel = newBox.children[0];
                        let isDouble = Math.ceil(Math.random() * 10) % 2;
                        if (isDouble == 1) {
                            scoreLabel.getComponent(cc.Label).string = 2 * this.level + "";
                        } else {
                            scoreLabel.getComponent(cc.Label).string = this.level + "";
                        }
                        this.node.addChild(newBox);
                        newBox.setPosition(-285 + i * (100 + 13), 450);
                        let colorArr = this.hslToRgb(this.level * 0.025, 0.5, 0.5);
                        newBox.color = cc.color(colorArr[0], colorArr[1], colorArr[2]);
                    }
                }
            }

            this.ballDown = false;
        }
    }

    addScore() {
        this.levelLabel.getComponent(cc.Label).string = "分数：" + (++this.score)
    }

    touchStart() {
        if (this.isActivity == false) {
            this.ballLink.node.setPosition(this.firstBallPositionX, this.lastBallPositionY);
        }
    }

    getAngle(x, y) {
        if (x === 0) {
            return y > 0 ? 90 : 270;
        }
        let a = Math.atan(y/x);
        let ret = a * 180 / Math.PI; //弧度转角度，方便调试
        if (x < 0) {
            ret = 180 + ret;
        }
        if (ret > 360) {
            ret -= 360;
        }
        if (ret < 0) {
            ret += 360;
        }
        return ret;
    }

    touchMove(event) {
        if (this.isActivity == false) {
            this.ballLink.enabled = true;

            let touchX = event.touch._point.x + this.lastBallPositionX - 320;
            let touchY = event.touch._point.y - this.lastBallPositionY;
            let angle = this.getAngle(touchX, touchY)
            if (angle < 15 || angle > 270) {
                angle = 15;
            } else if (angle > 165) {
                angle = 165;
            }
            this.ballLink.node.angle = angle
        }
    }

    touchEnd() {
        if (this.isActivity == false) {
            this.tipsLabel.node.runAction(cc.fadeOut(1))
            this.ballLink.enabled = false;
            if (this.isBegin == false) {
                this.isBegin = true;
            }
            let angle = this.ballLink.node.angle
            if (angle < 15 || angle > 270) {
                angle = 15;
            } else if (angle > 165) {
                angle = 165;
            }
            let toX = Math.cos(angle * 0.017453293) * 1500;
            let toY = Math.sin(angle * 0.017453293) * 1500;
            let vec = cc.v2(toX, toY)
            this.lastBallPositionX = this.firstBallPositionX;
            let count = this.allBalls - 1
            // this.indexBall.enabled = false;
            this.isFirstBall = false;
            this.schedule(function() {
                let ball = cc.instantiate(this.ballPrefab);
                ball.parent = this.gameNode
                ball.game = this;
                ball.setPosition(this.lastBallPositionX, this.lastBallPositionY);
                let boxRigidBody = ball.getComponent(cc.RigidBody);
                boxRigidBody.linearVelocity = vec;
            }.bind(this), 0.08, count)
            
            this.isActivity = true;
        }
    }

    showGameOver() {
        cc.director.loadScene('bounceGame');
    }

    update (dt) {
        if (this.ballDown == true) {
            this.initBox();
        }
        
        if(this.isFirstBall == true) {
            this.indexBall.enabled = true;
            this.indexBall.node.setPosition(this.firstBallPositionX, this.lastBallPositionY);
        }
    }

    hslToRgb(h, s, l) {
        let r, g, b;
        if(s == 0) {
            r = g = b = l; // achromatic
        } else {
            let hue2rgb = function hue2rgb(p, q, t) {
                if(t < 0) t += 1;
                if(t > 1) t -= 1;
                if(t < 1/6) return p + (q - p) * 6 * t;
                if(t < 1/2) return q;
                if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
                return p;
            }
            let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            let p = 2 * l - q;
            r = hue2rgb(p, q, h + 1/3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1/3);
        }
        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }
}
